(function() {
  'use strict';
  // サブドメインバリデーション API エンドポイント
  // refer to: http://wiki.dev.cybozu.co.jp/pages/viewpage.action?pageId=27330742
  // 本番用
  var CHECK_DUPLICATION_ACCOUNT = 'https://store.cybozu.com/api/open/developer/availableAccount.json';

  // テスト用
  // var CHECK_DUPLICATION_DOMAIN = 'https://store.cybozu-dev.com/api/open/trial/validateSubdomain.json';

  // 仮サインアップ API エンドポイント
  // refer to: http://wiki.dev.cybozu.co.jp/pages/viewpage.action?pageId=27330705
  // 本番用
  // var SIGNUP_URL = 'https://store.cybozu.com/api/open/developer/availableAccount.json';
  // テスト用
  // var SIGNUP_URL = 'https://store.cybozu-dev.com/api/open/trial/signup.json';

  // Zendesk アカウント情報取得 エンドポイント
  var ZENDESK_URL = 'https://developer.cybozu.io/api/v2/users/me.json';

  // 各 API 1回だけリクエスト判定フラグ
  var isCompletedReqZendesk = false;
  var isCompletedReqAccount = false;

  // フォーム非表示 + 値挿入 サンプルコード
  // フォームの DOM が作成される前イベント
  fb.events.form.created = [function(state) {
    // 「devnetID」 Zendesk API
    state.fields[5].validations.push({
      params: [],
      rule: 'custom_validation_zendeskInfo'
    });
    return state;
  }];

  // フォームの DOM が作成された後イベント
  fb.events.form.mounted = [function(state) {
    // 仮サインアップキー 確認 API
    state.fields[7].validations.push({
      params: [],
      rule: 'custom_validation_duplicate'
    });

    // 申込みボタン文言変更
    document.getElementsByClassName('fb-submit')[0].textContent = '申込み';

    // メールアドレス注意文言追加
    var disc = document.createElement('div');
    disc.innerText = '※ ログインアカウントで登録されているメールアドレスが設定されています。\n' +
                     '　 編集する場合はdeveloper networkのプロフィール設定画面より、メールアドレスを変更してください。';
    var mailParentNode = fb.getElementByCode('Email').parentNode;
    mailParentNode.appendChild(disc);
    disc.style.fontSize = '12px'
    mailParentNode.style.width = '750px';
    mailParentNode.style.height = '150px';
    mailParentNode.style.display = 'block';

    return state;
  }];

  // フォームの完了画面が作成された後イベント
  fb.events.finish.mounted = [function(state) {
    if (location.hash !== '#/finish') return state;
    // 完了メッセージを描画
    renderFinishMsg();
    return state;
  }];

  /** **********************
   * API を実行している関数群
   *************************/
  // ドメイン名重複チェック
  function checkAccountDuplicate(state) {
    var body = {
      account: state.record.Email.value
    };

    return axios.post(CHECK_DUPLICATION_ACCOUNT, body).then(function(resp) {

      // API 自体のエラーの場合
      if (!resp.data.available) {
        renderError(createErrorMessage('set', 'domain', 'err1'));
        return false;
      }

      // ドメイン使用可能場合
      // isCompletedReqAccount = true;
      return true;

    }).catch(function(err) {

      // リクエスト自体に失敗した場合
      renderError(createErrorMessage('set', 'domain', 'err2'));
      return false;

    });
  }

  // Zendesk ID, Email 入力
  function initZendeskInfo(state) {
    var header = {
      'Content-Type': 'application/json'
    };
    return axios.get(ZENDESK_URL, header).then(function(resp) {
      if (resp.status === 200) {
        // Zendesk ID や Email が取得できない場合
        if (!resp.data.user.id || !resp.data.user.email) {
          renderError(createErrorMessage('set', 'zendeskid', 'err2'));
          return false;
        }
        // フォームに値挿入
        state.record.DevnetId.value = resp.data.user.id;
        state.record.Email.value = resp.data.user.email;

        // 一回目のリクエスト終了
        isCompletedReqZendesk = true;
        return true;
      }
      return false;
    }).catch(function(err) {
      renderError(createErrorMessage('set', 'zendeskid', 'err1'));
      return false;
    });
  }

  /** **********************
   * 各エラーの定義
   * 非同期処理を使用しているので、validator の中で定義する
   *************************/
  fb.addValidators = function(state) {
    return {

      // ドメイン重複エラー
      custom_validation_duplicate: {
        getMessage: function(fieldCode, params) {
          return '';
        },
        validate: function(value, params) {
          // 項目でエラーになっている場合
          var errorElm = document.getElementsByClassName('el-form-item__error');
          var isError = false;
          for (var i = 0; i < errorElm.length; i++) {
            // エラー文言の要素のスタイルが display none 削除されているとき（＝表示されているとき）
            if (!errorElm[i].style[0]) {
              isError = true;
            }
          }
          if (isError) return false;

          // 2回目以降のリクエストの場合
          // if (isCompletedReqAccount) return true;

          return checkAccountDuplicate(state);
        }
      },
      // Zendesk ID, email 取得
      custom_validation_zendeskInfo: {
        getMessage: function(fieldCode, Params) {
          return '';
        },
        validate: function(value, params) {
          // 項目でエラーになっている場合
          var errorElm = document.getElementsByClassName('el-form-item__error');
          var isError = false;
          for (var i = 0; i < errorElm.length; i++) {
            if (!errorElm[i].style[0]) {
              isError = true;
            }
          }
          if (isError) {
            return false;
          }

          // 2回目以降のリクエストの場合
          if (isCompletedReqZendesk) return true;

          return initZendeskInfo(state);
        }
      }
    };
  };


  // エラー描画関数
  function renderError(msg) {
    var errDiv = document.getElementById('devLAPFbError');
    var errBlock = document.createElement('span');
    // 重複禁止
    if (document.getElementsByClassName('alert').length) return;
    errBlock.classList.add('alert');
    errBlock.classList.add('alert-block');
    errBlock.textContent = msg;
    errDiv.appendChild(errBlock);
  }

  // エラー文言
  function createErrorMessage(event, type, errorNum) {
    var errMsgToComu = '問題が発生しました。お手数ですが、しばらくたってから再度お申し込みください。\n' +
                    'この現象が多発する場合は、エラー番号と合わせてコミュニティの開発者ライセンストピックよりお問合せください。';
    var errMsgToMail = 'このメールアドレスで過去に開発者ライセンスまたは30日間の試用環境の申し込みをされています。\n' +
                 'お手数ですが、developer networkのプロフィール設定画面より、メールアドレスを変更の上、再度お申し込みください。\n' +
                 '※パスワード忘れの場合は、メールアドレス変更による再申し込みは必要ありません。サイボウズドットコム ストアよりパスワード変更をお願いします。';
    var errMsgDos = '同一IPから一定の時間内に上限を超えるリクエストを送信した。'

    var errorMessages = {
      'set': {
        'domain': {
          'err1': 'エラー番号：SD-001\n' + errMsgToMail,
          'err2': 'エラー番号：SD-002\n' + errMsgDos,
        },
        'zendeskid': {
          'err1': 'エラー番号：SZ-001\n' + errMsgToComu,
          'err2': 'エラー番号：SZ-002\n' + errMsgToComu,
        }
      }
    };
    return errorMessages[event][type][errorNum];
  }

  function renderFinishMsg() {
    var finishDiv = document.getElementById('finish');
    finishDiv.classList.add('alert');
    finishDiv.classList.add('alert-block');
    var finishMsg = '<p>申込みが完了しました。<br>' +
    '・開発者ライセンスの発行が完了次第、<br>' +
    '　申込みいただいたメールアドレス宛に環境情報を記載したメールをお送りします。<br>' +
    '・開発者ライセンス発行には最大30分ほどお待ちいただくことがございます。<br>' +
    '　翌営業日になってもメールが到着しない場合は、<br>' +
    '　お手数ですがコミュニティの<a href="https://developer.cybozu.io/hc/ja/community/topics/200079864">開発者ライセンストピック</a>にてお問い合わせください。</p>' +
    '<p><span class="wysiwyg-color-red"><strong>※ 回答が正しく送信されない可能性があるため、ブラウザの戻るボタンは使用しないでください。</strong></span></p>';

    finishDiv.innerHTML = finishMsg;
  }

})();